﻿/********************************************************
 * Module Name    : Workflow
 * Purpose        : Displays valid Document Action Options based on context
 * Class Used     : 
 * Chronological Development
 * Raghunandan sharma     08-Dec-2010
 ******************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Forms;
using VAdvantage.Classes;
using VAdvantage.Common;
using VAdvantage.DataBase;
using VAdvantage.Model;
//using VAdvantage.WF;
using VAdvantage.Process; using VAdvantage.ProcessEngine;
using VAdvantage.Utility;
using VAdvantage.Logging;
using VAdvantage.Model;
using VAdvantage.Grids;
using System.Data;
using VAdvantage.WF;

namespace VAdvantage.Framework
{
    /// <summary>
    /// Displays valid Document Action Options based on context
    /// </summary>
    public partial class VDocAction : ChildWindow
    {
        Context ctx = Utility.Envs.GetContext();

        private int windowNum = 0;
        private int AD_Table_ID;
        private bool _OKpressed = false;
        private bool _batch = false;
        private GridTab tab;
        //
        private static String[] _values = null;
        private static String[] _names;
        private static String[] _descriptions;
        //	Logger
        private static VLogger log = VLogger.GetVLogger(typeof(VDocAction).FullName);

        /// <summary>
        /// Constructor. GetNumberOfOptions()is used to determine to show the dialog
        /// </summary>
        /// <param name="WindowNo">window no</param>
        /// <param name="mTab">tab</param>
        /// <param name="button">button</param>
        /// <param name="Record_ID">record id</param>
        public VDocAction(int windowNo, GridTab tabObj, VAdvantage.Controls.IButton button, int Record_ID)
        //: base(false, false, false, false, Msg.Translate(Env.GetCtx(), "DocAction"))
        {
            base.Title = Msg.Translate(Envs.GetCtx(), "DocAction");
            windowNum = windowNo;
            tab = tabObj;
            InitializeComponent();
            LayoutRoot.Background = new SolidColorBrush(GlobalVariable.WINDOW_BACK_COLOR);
            // set font of this window
            //InitialFormSetting.SetFont(this);//silverlight comment
            //	dynamic init preparation
            AD_Table_ID = ctx.GetContextAsInt(windowNo, "BaseTable_ID");


            System.Threading.ThreadPool.QueueUserWorkItem(delegate
            {
                if (_values == null || _values.Length == 0)
                {
                    ReadReference();
                }
                DynInit(Record_ID);
                System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => FillCombo(options, index, defaultV, docStatus));
            });
            SetBusy(true);
            this.Show();
           
        }



        private void  SetBusy(bool value)
        {
            this.HasCloseButton = !value;
            busyWindow.Visibility = value ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
            txtBusy.Visibility = value ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
        }


        private void VDocAction_Load(object sender, EventArgs e)
        {
            vlblAction.Content = Utility.Msg.Translate(ctx, "DocAction");
            // set tooltip to all buttons
            ToolTipService.SetToolTip(ibtnBackground, Msg.GetMsg(Envs.GetContext(), "StartBackground", true));
            ToolTipService.SetToolTip(ibtnCancel, Msg.GetMsg(Envs.GetContext(), "Cancel", true));
            ToolTipService.SetToolTip(ibtnOk, Msg.GetMsg(Envs.GetContext(), "Ok", true));
        }

        /// <summary>
        /// Fill Vector with DocAction Ref_List(135) values
        /// </summary>
        private void ReadReference()
        {
            String sql;
            if (Utility.Envs.IsBaseLanguage(ctx, "AD_Ref_List"))//    GlobalVariable.IsBaseLanguage())//   Env.isBaseLanguage(ctx, "AD_Ref_List"))
                sql = "SELECT Value, Name, Description FROM AD_Ref_List "
                    + "WHERE AD_Reference_ID=135 ORDER BY Name";
            else
                sql = "SELECT l.Value, t.Name, t.Description "
                    + "FROM AD_Ref_List l, AD_Ref_List_Trl t "
                    + "WHERE l.AD_Ref_List_ID=t.AD_Ref_List_ID"
                    + " AND t.AD_Language='" + Utility.Envs.GetAD_Language(ctx) + "'"
                    + " AND l.AD_Reference_ID=135 ORDER BY t.Name";

            List<String> valueLst = new List<String>();
            List<String> nameLst = new List<String>();
            List<String> descriptionLst = new List<String>();

            IDataReader dr = null;
            try
            {
                dr = DB.ExecuteReader(sql, null, null);
                while (dr.Read())
                {
                    string value = dr["Value"].ToString();
                    string name = dr["Name"].ToString();
                    string description = dr["Description"].ToString();
                    if (description == null)
                        description = "";
                    //
                    valueLst.Add(value);
                    nameLst.Add(name);
                    descriptionLst.Add(description);
                }
                dr.Close();

            }
            catch (Exception e)
            {
                if (dr != null)
                {
                    dr.Close();
                }
                log.Log(Level.SEVERE, sql, e);
            }
            finally
            {
                if (dr != null)
                {
                    dr.Close();
                }
            }

            //	convert to arrays
            int size = valueLst.Count;
            _values = new String[size];
            _names = new String[size];
            _descriptions = new String[size];
            for (int i = 0; i < size; i++)
            {
                _values[i] = (String)valueLst[i];
                _names[i] = (String)nameLst[i];
                _descriptions[i] = (String)descriptionLst[i];
            }
        }
        String[] options;
        int index = 0;
        String defaultV = "";
        String docStatus = null;

        

        /// <summary>
        /// Determine valid DocActions based on DocStatus for the different documents.
        /// </summary>
        /// <pre>
        /// DocStatus (131)
        ///	    ??                 Unknown
        ///	    AP *               Approved
        ///	    CH                 Changed
        ///	    CL *               Closed
        ///	    CO *               Completed
        ///	    DR                 Drafted
        ///	    IN                 Invalid
        ///	    IP                 In Progress 
        ///	    NA                 Not Approved
        ///	    PE                 Posting Error
        ///	    PO *               Posted
        ///	    PR *               Printed
        ///	    RE                 Reversed
        ///	    TE                 Transfer Error
        ///	    TR *               Transferred
        ///	    VO *               Voided
        ///	    XX                 Being Processed
        ///	    
        /// DocAction (135)
        ///     --                 None
        ///	    AP *               Approve
        ///	    CL *               Close
        ///	    CO *               Complete
        ///	    IN                 Invalidate 
        ///	    PO *               Post
        ///	    PR *               Prepare
        ///	    RA                 Reverse - Accrual
        ///	    RC                 Reverse - Correction
        ///	    RE                 RE-activate
        ///	    RJ                 Reject
        ///	    TR *               Transfer
        ///	    VO *               Void
        ///	    WC                 Wait Complete
        ///	    XL                 Unlock
        /// </pre> 
        /// <param name="Record_ID">id</param>
        private void DynInit(int Record_ID)
        {
            docStatus = (String)tab.GetValue("DocStatus");
            String docAction = (String)tab.GetValue("DocAction");
            //
            Object processing = tab.GetValue("Processing");
            String orderType = ctx.GetContext(windowNum, "OrderType");
            bool isSOTrx = ctx.IsSOTrx(windowNum);

            //line commented for primary thread
            //if (docStatus == null)
            //{
            //    vlblMessage.Content = "*** ERROR ***";
            //    return;
            //}

            log.Fine("DocStatus=" + docStatus
                + ", DocAction=" + docAction + ", OrderType=" + orderType
                + ", IsSOTrx=" + isSOTrx + ", Processing=" + processing
                + ", AD_Table_ID=" + AD_Table_ID + ", Record_ID=" + Record_ID);
            //
            options = new String[_values.Length];

            /**
             * 	Check Existence of Workflow Acrivities
             */
            String wfStatus = MWFActivity.GetActiveInfo(ctx, AD_Table_ID, Record_ID);
            if (wfStatus != null)
            {
                Dispatcher.BeginInvoke(()=> 
                ShowMessage.Error("WFActiveForRecord", true, wfStatus));
                return;
            }

            //	Status Change
            if (!CheckStatus(tab.GetTableName(), Record_ID, docStatus))
            {
                Dispatcher.BeginInvoke(()=> 
                    {
                        ShowMessage.Error("DocumentStatusChanged", true);
                    });
                return;
            }

            /*******************
             *  General Actions
             */

            //	Locked
            if (processing != null)
            {
                bool locked = "Y".Equals(processing);
                if (!locked && processing.GetType() == typeof(Boolean))
                    locked = ((Boolean)processing);
                if (locked)
                    options[index++] = DocumentEngine.ACTION_UNLOCK;
            }

            //	Approval required           ..  NA
            if (docStatus.Equals(DocumentEngine.STATUS_NOTAPPROVED))
            {
                options[index++] = DocumentEngine.ACTION_PREPARE;
                options[index++] = DocumentEngine.ACTION_VOID;
            }
            //	Draft/Invalid				..  DR/IN
            else if (docStatus.Equals(DocumentEngine.STATUS_DRAFTED)
                || docStatus.Equals(DocumentEngine.STATUS_INVALID))
            {
                options[index++] = DocumentEngine.ACTION_COMPLETE;
                //	options[index++] = DocumentEngine.ACTION_Prepare;
                options[index++] = DocumentEngine.ACTION_VOID;
            }
            //	In Process                  ..  IP
            else if (docStatus.Equals(DocumentEngine.STATUS_INPROGRESS)
                || docStatus.Equals(DocumentEngine.STATUS_APPROVED))
            {
                options[index++] = DocumentEngine.ACTION_COMPLETE;
                options[index++] = DocumentEngine.ACTION_VOID;
            }
            //	Complete                    ..  CO
            else if (docStatus.Equals(DocumentEngine.STATUS_COMPLETED))
            {
                options[index++] = DocumentEngine.ACTION_CLOSE;
            }
            //	Waiting Payment
            else if (docStatus.Equals(DocumentEngine.STATUS_WAITINGPAYMENT)
                || docStatus.Equals(DocumentEngine.STATUS_WAITINGCONFIRMATION))
            {
                options[index++] = DocumentEngine.ACTION_VOID;
                options[index++] = DocumentEngine.ACTION_PREPARE;
            }
            //	Closed, Voided, REversed    ..  CL/VO/RE
            else if (docStatus.Equals(DocumentEngine.STATUS_CLOSED)
                || docStatus.Equals(DocumentEngine.STATUS_VOIDED)
                || docStatus.Equals(DocumentEngine.STATUS_REVERSED))
                return;

            /********************
             *  Order
             */
            if (AD_Table_ID == MOrder.Table_ID)
            {
                //	Draft                       ..  DR/IP/IN
                if (docStatus.Equals(DocumentEngine.STATUS_DRAFTED)
                    || docStatus.Equals(DocumentEngine.STATUS_INPROGRESS)
                    || docStatus.Equals(DocumentEngine.STATUS_INVALID))
                {
                    options[index++] = DocumentEngine.ACTION_PREPARE;
                    options[index++] = DocumentEngine.ACTION_CLOSE;
                    //	Draft Sales Order Quote/Proposal - Process
                    if (isSOTrx
                        && ("OB".Equals(orderType) || "ON".Equals(orderType)))
                        docAction = DocumentEngine.ACTION_PREPARE;
                }
                //	Complete                    ..  CO
                else if (docStatus.Equals(DocumentEngine.STATUS_COMPLETED))
                {
                    options[index++] = DocumentEngine.ACTION_VOID;
                    options[index++] = DocumentEngine.ACTION_REACTIVATE;
                }
                else if (docStatus.Equals(DocumentEngine.STATUS_WAITINGPAYMENT))
                {
                    options[index++] = DocumentEngine.ACTION_REACTIVATE;
                    options[index++] = DocumentEngine.ACTION_CLOSE;
                }
            }
            /********************
             *  Shipment
             */
            else if (AD_Table_ID == MInOut.Table_ID)
            {
                //	Complete                    ..  CO
                if (docStatus.Equals(DocumentEngine.STATUS_COMPLETED))
                {
                    options[index++] = DocumentEngine.ACTION_VOID;
                    options[index++] = DocumentEngine.ACTION_REVERSE_CORRECT;
                }
            }
            /********************
             *  Invoice
             */
            else if (AD_Table_ID == MInvoice.Table_ID)
            {
                //	Complete                    ..  CO
                if (docStatus.Equals(DocumentEngine.STATUS_COMPLETED))
                {
                    options[index++] = DocumentEngine.ACTION_VOID;
                    options[index++] = DocumentEngine.ACTION_REVERSE_CORRECT;
                }
            }
            /********************
             *  Payment
             */
            else if (AD_Table_ID == MPayment.Table_ID)
            {
                //	Complete                    ..  CO
                if (docStatus.Equals(DocumentEngine.STATUS_COMPLETED))
                {
                    options[index++] = DocumentEngine.ACTION_VOID;
                    options[index++] = DocumentEngine.ACTION_REVERSE_CORRECT;
                }
            }
            /********************
             *  GL Journal
             */
            //else if (AD_Table_ID == MJournal.Table_ID || AD_Table_ID == MJournalBatch.Table_ID)
            //{
            //    //	Complete                    ..  CO
            //    if (docStatus.Equals(DocumentEngine.STATUS_COMPLETED))
            //    {
            //        options[index++] = DocumentEngine.ACTION_REVERSE_CORRECT;
            //        options[index++] = DocumentEngine.ACTION_REVERSE_ACCRUAL;
            //    }
            //}
            /********************
             *  Allocation
             */
            else if (AD_Table_ID == MAllocationHdr.Table_ID)
            {
                //	Complete                    ..  CO
                if (docStatus.Equals(DocumentEngine.STATUS_COMPLETED))
                {
                    options[index++] = DocumentEngine.ACTION_VOID;
                    options[index++] = DocumentEngine.ACTION_REVERSE_CORRECT;
                }
            }
            /********************
             *  Bank Statement
             */
            else if (AD_Table_ID == MBankStatement.Table_ID)
            {
                //	Complete                    ..  CO
                if (docStatus.Equals(DocumentEngine.STATUS_COMPLETED))
                {
                    options[index++] = DocumentEngine.ACTION_VOID;
                }
            }
            /********************
             *  Inventory Movement, Physical Inventory
             */
            else if (AD_Table_ID == MMovement.Table_ID
                || AD_Table_ID == MInventory.Table_ID)
            {
                //	Complete                    ..  CO
                if (docStatus.Equals(DocumentEngine.STATUS_COMPLETED))
                {
                    options[index++] = DocumentEngine.ACTION_VOID;
                    options[index++] = DocumentEngine.ACTION_REVERSE_CORRECT;
                }
            }

            /***For Primary thread***/
            ///**
            // *	Fill actionCombo
            // */
            //for (int i = 0; i < index; i++)
            //{
            //    //	Serach for option and add it
            //    bool added = false;
            //    for (int j = 0; j < _values.Length && !added; j++)
            //        if (options[i].Equals(_values[j]))
            //        {
            //            //actionCombo.addItem(_names[j]);
            //            vcmbAction.Items.Add(_names[j]);
            //            added = true;
            //        }
            //}

            //	setDefault
            if (docAction.Equals("--"))		//	If None, suggest closing
                docAction = DocumentEngine.ACTION_CLOSE;

            for (int i = 0; i < _values.Length && defaultV.Equals(""); i++)
                if (docAction.Equals(_values[i]))
                    defaultV = _names[i];

            /***For Primary thread***/
            //if (!defaultV.Equals(""))
            //{
            //    //vcmbAction.SelectedValue = defaultV;
            //    vcmbAction.SelectedItem = defaultV;
            //}
        }

        private void FillCombo(String[] options, int index, String defaultV, string docStatus)
        {
            if (docStatus == null)
            {
                vlblMessage.Content = "*** ERROR ***";
                SetBusy(false);
                return;
            }
            /**
                 *	Fill actionCombo
                 */
            for (int i = 0; i < index; i++)
            {
                //	Serach for option and add it
                bool added = false;
                for (int j = 0; j < _values.Length && !added; j++)
                    if (options[i].Equals(_values[j]))
                    {
                        //actionCombo.addItem(_names[j]);
                        vcmbAction.Items.Add(_names[j]);
                        added = true;
                    }
            }

            if (!defaultV.Equals(""))
            {
                //vcmbAction.SelectedValue = defaultV;
                vcmbAction.SelectedItem = defaultV;
            }

            if (GetNumberOfOptions() == 0)
            {
                //this.Close();// Dispose();
                this.DialogResult = false;

                ShowMessage.Info("Info", true, "DocAction - No Options", ""); 
                log.Info("DocAction - No Options");
                SetBusy(false);
                return;
            }
            SetBusy(false);
        }

        /// <summary>
        /// Check Status Change
        /// </summary>
        /// <param name="tableName">table name</param>
        /// <param name="Record_ID">record id</param>
        /// <param name="docStatus">current doc status</param>
        /// <returns>true if status not changed</returns>
        private bool CheckStatus(String tableName, int Record_ID, String docStatus)
        {
            String sql = "SELECT COUNT(*) FROM " + tableName
                + " WHERE " + tableName + "_ID=" + Record_ID
                + " AND DocStatus='" + docStatus + "'";
            int result = Utility.Util.GetValueOfInt(DB.ExecuteScalar(sql));
            return result > 0;
        }

        /// <summary>
        /// Number of options available (to decide to display it)
        /// </summary>
        /// <returns>item count</returns>
        public int GetNumberOfOptions()
        {
            return vcmbAction.Items.Count;
        }

        /// <summary>
        /// Should the process be started?
        /// </summary>
        /// <returns>OK pressed</returns>
        public bool IsStartProcess()
        {
            return _OKpressed;
        }

        /// <summary>
        /// Should the process be started in batch?
        /// </summary>
        /// <returns>batch</returns>
        public bool IsBatch()
        {
            return _batch;
        }

        /// <summary>
        /// Get index of selected choice
        /// </summary>
        /// <returns>index or -1</returns>
        private int GetSelectedIndex()
        {
            int index = -1;

            if (vcmbAction.SelectedItem == null)
                return index;
            //	get Selection
            String sel = vcmbAction.SelectedItem.ToString();

            //	find it in vector
            for (int i = 0; i < _names.Length && index == -1; i++)
                if (sel.Equals(_names[i]))
                    index = i;
            //
            return index;
        }

        /// <summary>
        /// Save to Database
        /// </summary>
        /// <returns>true if saved to Tab</returns>
        private bool Save()
        {
            int index = GetSelectedIndex();
            if (index == -1)
                return false;

            //	Save Selection
            log.Config("DocAction=" + _values[index]);
            tab.SetValue("DocAction", _values[index]);
            return true;
        }

        private void ibtnOk_MouseLeftButtonUp(object sender, RoutedEventArgs e)
        {
            
            Setbutton(false);
            if (Save())
            {
                _OKpressed = true;
                this.DialogResult = true;
            }

            Setbutton(true);
            
        }

        private void ibtnCancel_MouseLeftButtonUp(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
        }

        private void ibtnBackground_MouseLeftButtonUp(object sender, RoutedEventArgs e)
        {
            Setbutton(false);
            _batch = true;
            if (Save())
            {
                _OKpressed = true;
                this.DialogResult = true;
            }
            Setbutton(true);
        }

        private void Setbutton(bool isEnable)
        {
            this.Cursor = isEnable ? Cursors.Arrow : Cursors.Wait;
            this.IsEnabled = isEnable;
        }
        

        private void vcmbAction_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            int index = GetSelectedIndex();
            //	Display descriprion
            if (index != -1)
            {
                vlblMessage.Content = _descriptions[index];
                log.Finer("DocAction=" + _names[index] + " - " + _values[index]);
            }
        }

        private void busyWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
        }
    }
}

